/*
 * @copyright: Huang Ding
 * @Author: ding-cx
 * @Date: 2021-08-14 17:59:05
 * @LastEditors: ding
 * @LastEditTime: 2022-10-11 09:28:03
 * @Description: file content
 */

import { actions } from "../../http/actions";
import type { hc } from "../../hc";
import HcWanBaseCmdService from "./HcWanBaseCmdService";

const logPre = "[module-baseHaiQing-person] ";

/** 海清人员名单操作  */
export default class HcWanCmdPersonService extends HcWanBaseCmdService {
	/**
	 *
	 * 添加一个人员名单内容
	 *
	 * @param {hc.http.personInfo} person
	 * @param {{ picinfo?: string; picURI?: string }} pic
	 * @return {*}
	 * @memberof PersonService
	 */
	async addPerson(person: hc.http.personInfo, pic: { picinfo?: string; picURI?: string }) {
		if (!person.DeviceID || (person.IdType !== 0 && !person.IdType)) {
			this.app.logger.error(
				logPre + "修改名单，数据类型缺少必要字段person.DeviceID/person.Name -  %s %s",
				person.DeviceID,
				person.Name
			);
			throw new Error(`新增名单，数据类型缺少必要字段DeviceID/IdType`);
		}
		if (!pic.picinfo && !pic.picURI) {
			this.app.logger.error(logPre + "新增名单，缺少人员照片数据 入参pic：%j", pic);
			throw new Error(`新增名单，缺少人员照片`);
		}
		const data: hc.http.AddPerson = {
			operator: actions.AddPerson,
			info: person,
			picinfo: pic.picinfo || undefined,
			picURI: pic.picinfo ? undefined : pic.picURI || undefined,
		};
		const res = await this.execCMD(actions.AddPerson, data, true);
		return res;
	}

	/**
	 *
	 * 修改一个人员名单
	 *
	 * @param {hc.http.personInfo} person
	 * @param {{ picinfo?: string; picURI?: string }} pic
	 * @return {*}
	 * @memberof PersonService
	 */
	async editPerson(person: hc.http.personInfo, pic: { picinfo?: string; picURI?: string }) {
		if (!person.DeviceID || (person.IdType !== 0 && !person.IdType)) {
			this.app.logger.error(
				logPre + "修改名单，数据类型缺少必要字段person.DeviceID/person.Name -  %s %s",
				person.DeviceID,
				person.Name
			);
			throw new Error(`修改名单，数据类型缺少必要字段DeviceID/IdType`);
		}
		if (!pic.picinfo && !pic.picURI) {
			this.app.logger.error(logPre + "修改名单，缺少人员照片数据 入参pic：%j", pic);
			throw new Error(`修改名单，缺少人员照片`);
		}
		const data: hc.http.editPerson = {
			operator: actions.EditPerson,
			info: person,
			picinfo: pic.picinfo || undefined,
			picURI: pic.picinfo ? undefined : pic.picURI || undefined,
		};
		return await this.execCMD(actions.AddPerson, data, true);
	}

	/** 根据customizID删除名单，执行方法。私有。 */
	private async delPersonExec(idType: 0 | 2, idList: number[] | string[]) {
		const deviceId = this.device.deviceId;
		const data: hc.http.deletePerson = {
			operator: actions.DeletePerson,
			info: {
				DeviceID: deviceId,
				IdType: idType,
				TotalNum: 1,
			},
		};
		if (idType === 0) {
			data.info.CustomizeID = idList as any;
		} else if (idType === 2) {
			data.info.PersonUUID = idList as any;
		}
		const res = await this.execCMD(actions.AddPerson, data, true);
		return res;
	}

	/**
	 *
	 * 删除一个人员 by customizeID
	 *
	 * @param {number} customizeID
	 * @return {*}
	 * @memberof PersonService
	 */
	async delPerson(customizeID: number) {
		const res = await this.delPersonExec(0, [customizeID]);
		this.app.logger.info(
			logPre + "机器deviceID %s 删除1个名单：customizeID:  %s",
			this.device.deviceId,
			customizeID
		);
		return res;
	}

	/**
	 *
	 * 删除多个人员 by customizeID Array
	 *
	 * @param {hc.wan.deviceId} deviceId 设备id
	 * @param {number[]} customizeIDList customizeID名单
	 * @return {*}
	 * @memberof PersonService
	 */
	async delPersonList(customizeIDList: number[]) {
		const res = await this.delPersonExec(0, customizeIDList);
		this.app.logger.info(
			logPre + "机器deviceID %s 删除多个名单：customizeID:  %j",
			this.device.deviceId,
			customizeIDList
		);
		return res;
	}

	/**
	 *
	 * 删除一个人员 by personUUID
	 *
	 * @param {hc.wan.deviceId} deviceId
	 * @param {string} personUUID 自定义uuid
	 * @return {*}
	 * @memberof PersonService
	 */
	async delPersonByPersonUUID(personUUID: string) {
		const res = await this.delPersonExec(2, [personUUID]);
		this.app.logger.info(
			logPre + "机器deviceID %s 删除1个名单：personUUID:  %s",
			this.device.deviceId,
			personUUID
		);
		return res;
	}

	/**
	 *
	 * 删除多个人员 by PersonUUID Array
	 *
	 * @param {hc.wan.deviceId} deviceId
	 * @param {number[]} PersonUUIDList
	 * @return {*}
	 * @memberof PersonService
	 */
	async delPersonListByPersonUUID(PersonUUIDList: number[]) {
		const res = await this.delPersonExec(2, PersonUUIDList);
		this.app.logger.info(
			logPre + "机器deviceID %s 删除多个名单：PersonUUIDList:  %j",
			this.device.deviceId,
			PersonUUIDList
		);
		return res;
	}

	/** 清空一个卡机全部名单 */
	async clearAllPerson() {
		const data: hc.http.deleteAllPerson = {
			operator: actions.DeleteAllPerson,
			info: {
				DeleteAllPersonCheck: 1,
			},
		};
		this.app.logger.warn(
			"正在执行敏感操作 海清设备清空所有名单 deviceId %s",
			this.device.deviceId
		);
		const res = await this.execCMD(data.operator, data, true);

		return res;
	}

	/**
	 *
	 * 查询单个名单信息
	 *
	 * @param {(string | number)} id id 查询id 可能是customizID 也可能是personUUID
	 * @param {boolean} [isPersonUUID=false] 是否是personUUID
	 * @return {*}
	 * @memberof PersonService
	 */
	async searchPerson(id: string | number, isPersonUUID: boolean = false) {
		const data: hc.http.searchPerson = {
			operator: actions.searchPerson,
			info: {
				DeviceID: this.device.deviceId,
				SearchType: isPersonUUID ? 1 : 0,
				SearchID: id,
				Picture: 0,
			},
		};
		const res = await this.execCMD<{ info: hc.http.personInfo }>(data.operator, data, true);
		return res;
	}

	/**
	 * 查询单个名单信息 包含照片
	 *
	 * @param {(string | number)} id 查询id 可能是customizID 也可能是personUUID
	 * @param {boolean} [isPersonUUID=false] 是否是personUUID
	 * @return {*}
	 * @memberof PersonService
	 */
	async getOnePersonPic(id: string | number, isPersonUUID: boolean = false) {
		const data: hc.http.searchPerson = {
			operator: actions.searchPerson,
			info: {
				DeviceID: this.device.deviceId,
				SearchType: isPersonUUID ? 1 : 0,
				SearchID: id,
				Picture: 1,
			},
		};
		const res = await this.execCMD<{
			info: hc.http.personInfo;
			/** base64照片 */
			picinfo: string;
		}>(data.operator, data, true);
		return res;
	}

	/** 查询机器人员名单总数（可选条件筛选）
	 * service.baseHaiQing.interface.person.searchPersonNum()
	 */
	async searchPersonNum(searchCondition?: hc.http.IRequestSearchPersonNumInfo) {
		const info = searchCondition || {
			DeviceID: this.device.deviceId,
		};
		const data = {
			operator: actions.SearchPersonNum,
			info: info,
		};
		const res = await this.execCMD<hc.http.IResponseSearchPersonNumInfo>(
			data.operator,
			data,
			true
		);
		return res;
	}
}
